package com.dc.spring.controller;

import com.alibaba.fastjson.JSON;
import com.dc.spring.bean.FirstBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

@RestController
@Slf4j
//@RequiredArgsConstructor
public class TestController {

    @Resource
    private FirstBean firstBean;

    @GetMapping("test1")
    public String test1(String aa) {
        String name = firstBean.getName();
        String s = firstBean.myMethon(aa);
        return s + name;
    }

    @GetMapping("test2")
    public String test2(String aa) throws ExecutionException, InterruptedException {
//        testf1();
//        thenApply(): 接收前一个任务的结果并返回新的结果。
//        thenAccept(): 接收前一个任务的结果但不返回结果。
//        thenRun(): 不接受任何参数并在前一个任务完成后执行。
//        testf2();
        testf3();


        return "1";
    }

    private void testf3() throws ExecutionException, InterruptedException {
        CompletableFuture<String> f3 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
                log.info("testf3 f3");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "a";
        });
        CompletableFuture<String> f4 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
                log.info("testf3 f4");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "b";
        });
        CompletableFuture<Void> f44 = CompletableFuture.allOf(f3, f4);
       FirstBean firstBean1 = new FirstBean("name");
        f44.thenRun(()->{
            try {
                String s = f3.get();
                firstBean1.setName(s);
                String s1 = f4.get();
                firstBean1.setName(s+s1);
                log.info("testf3 s1={}",s1);
                log.info("testf3 s={}",s);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } catch (ExecutionException e) {
                throw new RuntimeException(e);
            }
        }).get();

        log.info("test firstBean1 ={}", JSON.toJSONString(firstBean1));

    }

    private void testf2() throws ExecutionException, InterruptedException {
        CompletableFuture<String> f3 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(6000);
                log.info("test2 future2");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            return "a";
        });
        CompletableFuture<String> f33 = f3.thenApply(r -> {
            log.info("testf2 thenApply");
            sleepTest(5000);
            return r + "c";
        });
        CompletableFuture<Void> voidCompletableFuture = f33.thenAccept(r -> {
            log.info("testf2 thenAccept");
            sleepTest(3000);
        });
        String s = f33.get();
        log.info("testf2 f33={}",s);

        log.info("testf2 f33={}",voidCompletableFuture.get());
    }

    private void sleepTest(int i) {
        try {
            Thread.sleep(i);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private void testf1() {
        CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(10000);
                log.info("testf1 001");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> {
            try {
                Thread.sleep(9000);
                log.info("testf1 002");
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }
}
